package com.daffodil.core.jdbc;

import java.util.HashMap;
import java.util.Map;
import java.util.Properties;
import java.util.Set;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import javax.sql.DataSource;

import org.springframework.boot.autoconfigure.jdbc.DataSourceProperties;

import com.daffodil.util.file.FileUtils;
import com.daffodil.util.jasypt.JasyptUtils;

import lombok.extern.slf4j.Slf4j;

/**
 * 
 * @author yweijian
 * @date 2021年9月1日
 * @version 1.0
 * @description
 */
@Slf4j
public class DaffodilDataSourceProperties{

	//默认主数据源
	private static final String DEFALUT_KEY = "primary";

	private static final String DEFALUT_APPLICATION_NAME = "application.properties";

	private DataSourceProperties primary;

	Map<String, DataSourceProperties> datasource = new HashMap<String, DataSourceProperties>();

	public DaffodilDataSourceProperties() {
		super();
		this.buildDataSourceProperties(DEFALUT_APPLICATION_NAME);
		this.primary = this.getDatasource().get(DEFALUT_KEY);
	}

	/**
	 * 构建数据源配置
	 * @param resource
	 */
	private void buildDataSourceProperties(String resource) {
		Properties properties = FileUtils.getProperties(resource);
		this.build(properties);

		String include = properties.getProperty("spring.profiles.include");

		if(null != include && !"".equals(include.trim())) {
			String[] includes = include.split(",");
			for (int i = 0; i < includes.length; i++) {
				resource = "application-" + includes[i].trim() + ".properties";
				this.buildDataSourceProperties(resource);
			}
		}
	}

	/**
	 * @param properties
	 */
	@SuppressWarnings("unchecked")
	private void build(Properties properties) {
		String password = properties.getProperty("jasypt.encryptor.password");
		Set<String> set = properties.stringPropertyNames();
		set.forEach(item -> {
			Pattern pattern = Pattern.compile("daffodil\\.datasource\\.(.*)\\.(.*)");
			Matcher matcher = pattern.matcher(item);
			if(matcher.find()) {
				String fullKey = matcher.group();
				String lookupKey = matcher.group(1);
				String propertyKey = matcher.group(2);

				DataSourceProperties dataSourceProperties = this.datasource.get(lookupKey);
				if(null == dataSourceProperties) {
					dataSourceProperties = new DataSourceProperties();
				}
				String value = this.getPropertyValue(password, properties.getProperty(fullKey));
				
				switch (propertyKey) {
				case "driver-class-name":
					dataSourceProperties.setDriverClassName(value);
					break;
				case "url":
					dataSourceProperties.setUrl(value);
					break;
				case "username":
					dataSourceProperties.setUsername(value);
					break;
				case "password":
					dataSourceProperties.setPassword(value);
					break;
				case "data-source-type":
					try {
						Class<? extends DataSource> dataSourceType = (Class<? extends DataSource>) Class.forName(value);
						dataSourceProperties.setType(dataSourceType);
					} catch (ClassNotFoundException e) {
						log.error(e.getMessage(), e);
					}
					break;
				default:
					break;
				}

				this.datasource.put(lookupKey, dataSourceProperties);
			}
		});
	}

	/**
	 * 获取属性值，有些属性值需要解密比如用户名、密码
	 * @param password
	 * @param value
	 * @return
	 */
	private String getPropertyValue(String password, String value) {
		Pattern pattern = Pattern.compile("ENC\\((.*)\\)");
		Matcher matcher = pattern.matcher(value);
		if(matcher.find()) {
			value = matcher.group(1);
			value = JasyptUtils.decyptPwd(password, value);
		}
		return value;
	}
	
	public Map<String, DataSourceProperties> getDatasource() {
		return datasource;
	}

	public void setDatasource(Map<String, DataSourceProperties> datasource) {
		this.datasource = datasource;
	}

	public DataSourceProperties getPrimary() {
		return primary;
	}

	public void setPrimary(DataSourceProperties primary) {
		this.primary = primary;
	}

}
